package com.glq1218.common.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glq1218.common.dto.QueryUserListDTO;
import com.glq1218.common.dto.UserDTO;
import com.glq1218.common.entity.User;
import com.glq1218.common.mapper.RoleMapper;
import com.glq1218.common.mapper.UserMapper;
import com.glq1218.common.model.PageRes;
import com.glq1218.common.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 用户表 服务实现类
 *
 * @author glq1218
 * @since 2023-02-18
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final RoleMapper roleMapper;
    private final PasswordEncoder passwordEncoder;

    /**
     * 通过用户名查找用户
     * @param username 用户名
     * @return User对象
     */
    @Override
    public User findByUsername(String username) {
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(User::getUsername, username);
        return getOne(lambdaUpdateWrapper);
    }

    /**
     *
     * @param userInfo 用户的某一项信息
     * @param info     提供的信息
     * @return
     * @param <T>
     */
    @Override
    public <T> boolean isExist(SFunction<User, T> userInfo, String info) {
        LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(userInfo, info);
        User user = super.getOne(lambdaUpdateWrapper);
        return user != null;
    }

    @Override
    public PageRes<UserDTO> queryUserList(QueryUserListDTO queryUserListDTO) {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .like(queryUserListDTO.getUsername() != null, User::getUsername, queryUserListDTO.getUsername())
                .like(StringUtils.hasText(queryUserListDTO.getNickname()), User::getUsername, queryUserListDTO.getNickname());
        Page<User> userPage = new Page<>(queryUserListDTO.getCurrent(), queryUserListDTO.getPageSize());
        page(userPage, lambdaQueryWrapper);
        long total = userPage.getTotal();
        // 如果结果记录总数为0，直接返回
        if (total == 0) {
            return PageRes.<UserDTO>builder()
                    .total(total)
                    .build();
        }
        // 将User转为UserDTO
        IPage<UserDTO> convert = userPage.convert(user -> {
            UserDTO userVO = new UserDTO();
            BeanUtils.copyProperties(user, userVO);
            // 查询角色信息
            String[] roleNamesByUserId = roleMapper.getRoleNamesByUserId(userVO.getId());
            // 设置角色信息
            userVO.setRole(roleNamesByUserId);
            return userVO;
        });
        List<UserDTO> records = convert.getRecords();
        return PageRes.<UserDTO>builder()
                .list(records)
                .total(total)
                .build();
    }

    @Override
    public String addUser(UserDTO userDTO) {
        if (!StringUtils.hasText(userDTO.getUsername())) {
            throw new RuntimeException("用户名不能为空");
        }
        if (isExist(User::getUsername, userDTO.getUsername())) {
            throw new RuntimeException("用户名已注册");
        }
        if (isExist(User::getPhone, userDTO.getPhone())) {
            throw new RuntimeException("手机号已注册");
        }
        if (isExist(User::getEmail, userDTO.getEmail())) {
            throw new RuntimeException("邮箱已注册");
        }
        // 如果没有设置密码就默认为用户名
        if (!StringUtils.hasText(userDTO.getPassword())) {
            userDTO.setPassword(userDTO.getUsername());
        }
        userDTO.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        if (save(user)) {
            return "添加成功";
        }
        return "添加失败";
    }
}
